//
//  NHTPushService.m
//  PlantGrowthLamp
//
//  Created by NHT on 2023/10/28.
//

#import "NHTPushService.h"
#import "SocketRocketUtility.h"

//#import <UserNotifications/UserNotifications.h> <UNUserNotificationCenterDelegate>

@interface NHTPushService ()
///自动打开关闭socket
@property (nonatomic,assign) BOOL needAutomaticOpenSocket;
///是否时生产环境
@property (nonatomic,assign) BOOL appIsProduction;

///使用applyPushMessageBlock 来发送消息，通过通知获取注册结果、推送消息、socket消息时的block回调
@property (nonatomic,copy) void(^pushMessageBlock)(NSDictionary *messageDic,NSInteger messageType);

///接收到的所有数据
@property (nonatomic,strong) NSMutableArray  *allPushInfoArr;
@end

/**
 调用打开socket方法时步骤
 1、调用打开方法，赋值自动打开关闭socket（needAutomaticOpenSocket）的值为为true
 2、监听到app状态进入前台活跃，判断needAutomaticOpenSocket来确定是否自动打开socket
 3、监听到app即将进入后台，判断needAutomaticOpenSocket来确定是否自动关闭socket
 */

@implementation NHTPushService

/// 关闭socket连接
-(void)NHTPushSocketClose{
    self.needAutomaticOpenSocket = false;
    [[SocketRocketUtility instance] SRWebSocketClose];
}
/// 开启socket连接
-(void)NHTPushSocketOpen:(BOOL)isProduction resultBlock:(void (^)(NSInteger state))resultBlock{
    self.appIsProduction = isProduction;
    self.needAutomaticOpenSocket = true;
    
    [SocketRocketUtility instance].scoketMessageBlock = ^(NSDictionary *messageDic) {
        [self applyPushMessageBlock:messageDic messageType:2];
    };
    [SocketRocketUtility instance].socketStateChange = ^(SRReadyState socketReadyState) {
        ///处理socket状态改变
        resultBlock(socketReadyState);
    };
    
    if (self.deviceTokenFinal.length < 1){
        resultBlock(SR_CLOSED);
        return;
    }
    UIApplicationState state = [UIApplication sharedApplication].applicationState;
    if (state != UIApplicationStateActive){
        //非前台活跃状态
        resultBlock(SR_CLOSED);
        return;
    }
    [self openSocketFinalStep];
}

-(void)openSocketFinalStep{
    [[SocketRocketUtility instance] SRWebSocketOpenWithURLString:[self getNowSocketAdress]];
}

/// 注册推送服务
/// - Parameter resultBlock: 消息回调,messageType------0：注册结果；1推送消息；2socket消息；
-(void)NHTPushRegisterPushMessageBlock:(void (^)(NSDictionary *messageDic,NSInteger messageType))resultBlock{
    [self NHTPushRegisterPushType:UNAuthorizationOptionCarPlay | UNAuthorizationOptionSound | UNAuthorizationOptionBadge | UNAuthorizationOptionAlert pushMessageBlock:resultBlock];
}

/// 注册推送服务
/// - Parameters:
///   - options: 推送提示类型，比如 UNAuthorizationOptionSound | UNAuthorizationOptionAlert
///   - resultBlock: 消息回调,messageType------0：注册结果；1推送消息；2socket消息；
-(void)NHTPushRegisterPushType:(UNAuthorizationOptions)options pushMessageBlock:(void (^)(NSDictionary *messageDic,NSInteger messageType))resultBlock{
    self.pushMessageBlock = resultBlock;
    
    UIApplication *application = [UIApplication sharedApplication];
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
//    center.delegate = self;
    /// 在设备可以接受任何推送之前，调用请求授权会产生提示（是否打开推送，“允许”、“不允许”）：requestAuthorization
    [center requestAuthorizationWithOptions:UNAuthorizationOptionCarPlay | UNAuthorizationOptionSound | UNAuthorizationOptionBadge | UNAuthorizationOptionAlert completionHandler:^(BOOL granted, NSError * _Nullable error) {
        if (granted) {
            NSLog(@" iOS 10 request notification success");
        }else{
            NSLog(@" iOS 10 request notification fail");
        }
    }];
    
    [application registerForRemoteNotifications];
}


-(NSString *)getHexStringForData:(NSData *)data
{
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 13) {
        if (![data isKindOfClass:[NSData class]]) {
            return @"";
        }
        NSUInteger len = [data length];
        char *chars = (char *)[data bytes];
        NSMutableString *hexString = [[NSMutableString alloc]init];
        for (NSUInteger i=0; i<len; i++) {
            [hexString appendString:[NSString stringWithFormat:@"%0.2hhx" , chars[i]]];
        }
        return hexString;
    } else {
        NSString *myToken = [[data description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
        myToken = [myToken stringByReplacingOccurrencesOfString:@" " withString:@""];
        return myToken;
    }
}

-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    NSString *lastToken =  [self getHexStringForData:deviceToken];
    
//    NSLog(@"\n\n ****NHTPush**** \n deviceTokenStr:%@ \n\n",lastToken);
    [[NSUserDefaults standardUserDefaults] setObject:lastToken forKey:@"NHTPushDeviceToken"];//解析后deviceToken
    [[NSUserDefaults standardUserDefaults] setObject:deviceToken forKey:@"NHTPushDeviceTokenOriginal"];//原始deviceToken
    
    self.deviceTokenFinal = lastToken;
    self.deviceTokenOriginal = deviceToken;
    [self applyPushMessageBlock:@{@"result":@"success",@"deviceTokenStr":lastToken} messageType:0];
}

-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
    //Optional 实现注册 APNs 失败接口（可选）
    NSLog(@"\n\n ****NHTPush**** \n 注册失败: %@ \n\n", error);
    [self applyPushMessageBlock:@{@"result":@"fail",@"deviceTokenStr":@"",@"error":error} messageType:0];
}

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    /*如果想在后台的时候收到远程推送的时候能调用这个方法
     那么推送时后台必须加上参数
     "content-available":1
     */
    //前台后台都能收到
  
    [self applyPushMessageBlock:userInfo messageType:1];
    completionHandler(UIBackgroundFetchResultNewData);
}
///收到推送消息 int是为了适配uniapp
-(void)applicationUniApp:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(NSInteger))completionHandler{
    /*如果想在后台的时候收到远程推送的时候能调用这个方法
     那么推送时后台必须加上参数
     "content-available":1
     */
    //前台后台都能收到
  
    [self applyPushMessageBlock:userInfo messageType:1];
    completionHandler(UIBackgroundFetchResultNewData);
}
/**调用消息回调block*/
-(void)applyPushMessageBlock:(NSDictionary *)messageDic messageType:(NSInteger)messageType{
    if(_pushMessageBlock){
        self.pushMessageBlock(messageDic,messageType);
    }else{
        NSLog(@"===尚未赋值回调 pushMessageBlock====");
    }
}

//#pragma mark---UNUserNotificationCenterDelegate
//-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler{
//    NSLog(@"---点击进来---%@",response);
//}
//- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{
//    //前台能收到
//    /**
//     因为在uniapp x中只能通过此方法收到，为了适配添加了这个
//     */
//    [self handelPushInfo:notification.request.content.userInfo];
//    completionHandler(UNNotificationPresentationOptionSound);
//}
//-(void)handelPushInfo:(NSDictionary *)userInfo{
//    if([self.allPushInfoArr containsObject:userInfo]){
//        NSLog(@"重复消息-----");
//    }else{
//        [self.allPushInfoArr addObject:userInfo];
//        if(self.allPushInfoArr.count > 20){
//            [self.allPushInfoArr removeObjectsInRange:NSMakeRange(0, 10)];
//        }
//      [self applyPushMessageBlock:userInfo messageType:1];
//    }
//}
#pragma mark---配置用户socke链接地址
-(void)setUserSocketAdress:(NSString *)userSocketAdress{
    [[NSBundle mainBundle] bundleIdentifier];
    _userSocketAdress = userSocketAdress;
}
///获取当前socket地址
-(NSString *)getNowSocketAdress{
    if(_userSocketAdress == nil || self.userSocketAdress.length < 1){
        return self.appIsProduction ? @"wss://app-push.jbufacloud.com:8439/jkws/":@"http://122.115.233.174:8438/jkws/";
    }else{
        return  self.userSocketAdress;
    }
}

#pragma mark---单利
+(instancetype)shareNHTPush{
    static NHTPushService *sharePushService = nil;
    static dispatch_once_t onceTokern;
    dispatch_once(&onceTokern, ^{
        sharePushService = [[super allocWithZone:NULL] init];
        sharePushService.deviceTokenFinal = @"";
        sharePushService.allPushInfoArr = [NSMutableArray new];
        [[NSNotificationCenter defaultCenter] addObserver:sharePushService selector:@selector(stateChangeActive) name:UIApplicationDidBecomeActiveNotification  object:nil];//进入前台活跃
        [[NSNotificationCenter defaultCenter] addObserver:sharePushService selector:@selector(stateChangeWillResignActive) name:UIApplicationWillResignActiveNotification  object:nil];//即将进入后台
    });
    return sharePushService;
}
-(void)stateChangeActive{
//    NSLog(@"stateChangeActive");
    if (self.needAutomaticOpenSocket){
        [self openSocketFinalStep];
    }
}
-(void)stateChangeWillResignActive{
//    NSLog(@"stateChangeWillResignActive");
    if (self.needAutomaticOpenSocket){
        [[SocketRocketUtility instance] SRWebSocketClose];
    }
}
//用alloc返回也是唯一实例
+(id) allocWithZone:(struct _NSZone *)zone {
    return [NHTPushService shareNHTPush] ;
}
//对对象使用copy也是返回唯一实例
-(id)copyWithZone:(NSZone *)zone {
    return [NHTPushService shareNHTPush] ;//return _instance;
}
//对对象使用mutablecopy也是返回唯一实例
-(id)mutableCopyWithZone:(NSZone *)zone {
    return [NHTPushService shareNHTPush] ;
}

@end
